<template>
  <div class="menu-permission">
    <el-form :model="form" label-width="80px">
      <!-- 合并成一个按钮，支持切换展开/折叠 -->
      <el-button
        type="primary"
        @click="toggleExpand"
        :icon="isExpanded ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"
      >
        {{ isExpanded ? '折叠全部' : '展开全部' }}
      </el-button>

      <el-form-item label="权限配置">
        <el-tree
          ref="tree"
          :data="menu_list"
          show-checkbox
          node-key="menu_id"
          :default-checked-keys="form.ids"
          :props="defaultProps"
          check-strictly
          @check="handleCheck"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <span class="node-label">{{ node.label }}</span>
              <el-tag type="danger" v-if="data.type === 1" class="permission-tag">[接口-权限]</el-tag>
              <el-tag type="success"  v-else class="permission-tag">[菜单-权限]</el-tag>
            </span>
          </template>
        </el-tree>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :loading="loading" @click="onSubmit">保存</el-button>
        <el-button type="info" class="bs-left-10" @click="$router.back()">返回</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import api from '@/api/role'

export default {
  data() {
    return {
      loading: false,
      menu_list: [],
      form: {
        id: 0,
        ids: []
      },
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      isExpanded: false // 控制展开状态
    }
  },
  mounted() {
    if (this.$route.query.hasOwnProperty('id')) {
      this.form.id = this.$route.query.id
      this.getData(this.form.id)
    }
  },
  methods: {
    getData(id) {
      api.get_auths({ id: id }).then((res) => {
        if (res.code === 0) {
          this.form.ids = res.data.menu_ids
          this.menu_list = res.data.menu_list
        }
      })
    },
    handleCheck(data, checkedStatus) {
      const tree = this.$refs.tree
      if (checkedStatus.checkedKeys.includes(data.menu_id)) {
        this.checkAllChildren(tree, data)
        this.updateParentState(tree, data.parent_id)
      } else {
        this.uncheckAllChildren(tree, data)
        this.updateParentState(tree, data.parent_id)
      }
    },
    checkAllChildren(tree, data) {
      if (data.children && data.children.length > 0) {
        data.children.forEach(child => {
          tree.setChecked(child.menu_id, true)
          this.checkAllChildren(tree, child)
        })
      }
    },
    uncheckAllChildren(tree, data) {
      if (data.children && data.children.length > 0) {
        data.children.forEach(child => {
          tree.setChecked(child.menu_id, false)
          this.uncheckAllChildren(tree, child)
        })
      }
    },
    updateParentState(tree, parent_id) {
      const parent = this.findParent(this.menu_list, parent_id)
      if (!parent) return

      const children = parent.children || []
      const allChecked = children.every(child => this.isNodeChecked(tree, child.menu_id))
      const someChecked = children.some(child => this.isNodeChecked(tree, child.menu_id))

      if (allChecked) {
        tree.setChecked(parent.menu_id, true)
      } else if (someChecked) {
        tree.setChecked(parent.menu_id, false)
      } else {
        tree.setChecked(parent.menu_id, false)
      }

      this.updateParentState(tree, parent.parent_id)
    },
    findParent(list, menu_id) {
      for (let item of list) {
        if (item.menu_id === menu_id) return item
        if (item.children) {
          const found = this.findParent(item.children, menu_id)
          if (found) return found
        }
      }
      return null
    },
    isNodeChecked(tree, menu_id) {
      const checkedKeys = tree.getCheckedKeys()
      return checkedKeys.includes(menu_id)
    },
    onSubmit() {
      this.loading = true
      const checkedKeys = this.$refs.tree.getCheckedKeys()
      const halfCheckedKeys = this.$refs.tree.getHalfCheckedKeys()
      this.form.ids = [...checkedKeys, ...halfCheckedKeys]
      api.update_auths(this.form).then(() => {
        this.loading = false
        this.$message.success('操作成功')
      }).catch(() => {
        this.loading = false
      })
    },
    // 新增：合并成一个按钮，切换展开/折叠
    toggleExpand() {
      const tree = this.$refs.tree
      const nodes = tree.store._getAllNodes() // 获取所有节点

      if (this.isExpanded) {
        nodes.forEach(node => {
          node.expanded = false // 折叠所有节点
        })
      } else {
        nodes.forEach(node => {
          node.expanded = true // 展开所有节点
        })
      }

      // 强制更新视图（如果需要）
      this.$nextTick(() => {
        tree.store.defaultExpandedKeys = nodes.map(node => node.key)
      })

      this.isExpanded = !this.isExpanded // 切换状态
    }
  }
}
</script>

<style scoped>
.menu-permission {
  padding: 20px;
}

.custom-tree-node {
  display: flex;
  align-items: center;
  white-space: nowrap; /* 防止整体换行 */
  flex-wrap: nowrap; /* 禁止子元素换行 */
}

.node-label {
  flex: 1; /* 让节点标签占据剩余空间 */
  overflow: hidden;
  text-overflow: ellipsis; /* 超出部分显示省略号 */
  white-space: nowrap; /* 防止节点标签内部换行 */
  margin-right: 8px; /* 与权限标签保持间距 */
}

/*.permission-tag {
  flex-shrink: 0; !* 禁止权限标签缩小 *!
  !*padding: 2px 6px;*!
  background-color: #ecf5ff;
  border: 1px solid #d9ecff;
  border-radius: 4px;
  font-size: 12px;
  color: #409eff;
}*/

/* 全局样式：确保树形菜单容器宽度足够 */
.el-tree-node__content {
  white-space: nowrap !important; /* 防止树形节点整体换行 */
  min-width: 300px; /* 根据需要调整最小宽度 */
}
</style>
